﻿using System;
using System.Collections;
using System.Net.Sockets;
using System.Threading;

public delegate void InitSocketAction_Short(byte[] message);

public delegate void InitSocketAction_NoParameter();
public class ReconnectHandler
{

    Timer heartBeatTimer;
    private Timer checkTimeOut;

    //心跳委托
    public InitSocketAction_Short sendMessageAction;
    public InitSocketAction_NoParameter printAction;
    public InitSocketAction_NoParameter reconnectAction;

    private Socket socket;


    //心跳参数
    private bool IsTimeOut;
    private short timeOutSeconds;
    private int heartBeatPeriod;

    /// <summary>
    /// 开启心跳检测，传入需要检测的socket,心跳的间隔,连接失败后执行的函数委托
    /// </summary>
    /// <param name="sendMessageAction">发送函数</param>
    /// <param name="printAction">打印函数</param>
    /// <param name="reconnectAction">重连函数</param>
    /// <param name="hearBeatPeriod">心跳间隔</param>
    /// <param name="timeOutSeconds">超时上限</param>
    public ReconnectHandler(InitSocketAction_Short sendMessageAction,InitSocketAction_NoParameter printAction, InitSocketAction_NoParameter reconnectAction, int heartBeatPeriod, short timeOutSeconds)
    {    
        this.sendMessageAction = sendMessageAction;
        this.printAction = printAction;
        this.reconnectAction = reconnectAction;
        this.heartBeatPeriod = heartBeatPeriod;
        this.timeOutSeconds = timeOutSeconds;
    }

    /// <summary>
    /// 开始心跳检测
    /// </summary>
    /// <param name="socket"></param>
    public void StartHeartBeat(Socket socket)
    {
        if (heartBeatTimer != null) heartBeatTimer.Dispose();
        if (checkTimeOut != null) checkTimeOut.Dispose();
        this.socket = socket;
        heartBeatTimer = new Timer(HeartBeatAction, socket, heartBeatPeriod, heartBeatPeriod);
        if(timeOutSeconds != 0)
        checkTimeOut = new Timer(CheckHeartBeat,null,timeOutSeconds,timeOutSeconds);
    }

    public void ShutdownThread()
    {
        try
        {
            if (heartBeatTimer != null) heartBeatTimer.Dispose();
            if (checkTimeOut != null) checkTimeOut.Dispose();
        }
        catch (Exception)
        {
            
        }
    }

    public void HeartBeatAction()
    {
        IsTimeOut = false;
    }

    /// <summary>
    /// 服务器，发送-1给客户端，由客户端接收后检测与上一次时间差，大于8s则重连
    /// </summary>
    /// <param name="state"></param>
    private void HeartBeatAction(object state)
    {
        if (socket == null || !socket.Connected)
        {
            if (heartBeatTimer != null) heartBeatTimer.Dispose();
            if (checkTimeOut != null) checkTimeOut.Dispose();
            return;
        }
        try
        {
            printAction.Invoke();
            //发送-1
            short _type = -1;
            byte[] type = MessageController.GetInstance().WriteMessage(_type,0);
            sendMessageAction.Invoke(type);
        }
        catch (Exception)
        {
            
            throw;
        }
    }

    private void CheckHeartBeat(object state)
    {
        try
        {
            if (!IsTimeOut)
            {
                IsTimeOut = true;
            }
            else
            {
                //ipad端连接超时，等待重新连接
                if (socket != null)
                {
                    socket.Close();
                    reconnectAction.Invoke();
                }
            }
        }
        catch (Exception)
        {
            
        }
    }
}
